package com.kexio.user.dto;

import java.io.Serializable;
import java.time.LocalDateTime;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.kexio.common.page.PageQuery;
import com.kexio.user.entity.Tenant;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;

/**
 * 租户统一DTO
 * 
 * 用于租户信息的创建、更新、响应、分页查询等全部功能
 * 继承PageQuery支持分页，支持验证分组
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TenantDTO extends PageQuery implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    // ==================== 验证分组接口 ====================
    
    /**
     * 创建租户验证分组
     */
    public interface CreateGroup {}
    
    /**
     * 更新租户验证分组
     */
    public interface UpdateGroup {}
    
    // ==================== 基本字段 ====================
    
    /**
     * 主键ID（响应时使用）
     */
    private String id;
    
    /**
     * 租户标识（全局唯一）
     */
    @NotBlank(message = "租户标识不能为空", groups = CreateGroup.class)
    @Size(min = 2, max = 64, message = "租户标识长度必须在2-64个字符之间", 
          groups = {CreateGroup.class, UpdateGroup.class})
    @Pattern(regexp = "^[a-zA-Z0-9_-]+$", 
             message = "租户标识只能包含字母、数字、下划线和连字符", 
             groups = {CreateGroup.class, UpdateGroup.class})
    private String tenantId;
    
    /**
     * 租户名称
     */
    @NotBlank(message = "租户名称不能为空", groups = CreateGroup.class)
    @Size(min = 2, max = 128, message = "租户名称长度必须在2-128个字符之间",
          groups = {CreateGroup.class, UpdateGroup.class})
    private String tenantName;
    
    /**
     * 租户类型
     */
    @Pattern(regexp = "^(ENTERPRISE|STANDARD|TRIAL)$", 
             message = "租户类型必须是ENTERPRISE、STANDARD或TRIAL之一",
             groups = {CreateGroup.class, UpdateGroup.class})
    private String tenantType;
    
    /**
     * 租户状态
     */
    @Min(value = 0, message = "租户状态值不能小于0", groups = {CreateGroup.class, UpdateGroup.class})
    @Max(value = 4, message = "租户状态值不能大于4", groups = {CreateGroup.class, UpdateGroup.class})
    private Integer status;
    
    /**
     * 最大用户数限制
     */
    @Min(value = 1, message = "最大用户数不能小于1", groups = {CreateGroup.class, UpdateGroup.class})
    @Max(value = 100000, message = "最大用户数不能大于100000", groups = {CreateGroup.class, UpdateGroup.class})
    private Integer maxUsers;
    
    /**
     * 租户过期时间
     */
    private LocalDateTime expireTime;
    
    /**
     * 联系人姓名
     */
    @Size(max = 64, message = "联系人姓名长度不能超过64个字符",
          groups = {CreateGroup.class, UpdateGroup.class})
    private String contactName;
    
    /**
     * 联系人电话
     */
    @Pattern(regexp = "^1[3-9]\\d{9}$|^$", message = "联系人电话格式不正确",
             groups = {CreateGroup.class, UpdateGroup.class})
    private String contactPhone;
    
    /**
     * 联系人邮箱
     */
    @Email(message = "联系人邮箱格式不正确", groups = {CreateGroup.class, UpdateGroup.class})
    @Size(max = 128, message = "联系人邮箱长度不能超过128个字符",
          groups = {CreateGroup.class, UpdateGroup.class})
    private String contactEmail;
    
    /**
     * 租户描述信息
     */
    @Size(max = 512, message = "租户描述长度不能超过512个字符",
          groups = {CreateGroup.class, UpdateGroup.class})
    private String description;
    
    /**
     * 创建人ID
     */
    private String createdBy;
    
    /**
     * 创建时间
     */
    private LocalDateTime createdAt;
    
    /**
     * 最后更新人ID
     */
    private String updatedBy;
    
    /**
     * 最后更新时间
     */
    private LocalDateTime updatedAt;
    
    /**
     * 是否删除（0-未删除，1-已删除）
     */
    private Integer deleted;
    
    // ==================== 扩展字段 ====================
    
    /**
     * 租户下用户数量（响应时填充）
     */
    private Integer userCount;
    
    /**
     * 租户状态描述（响应时填充）
     */
    private String statusText;
    
    /**
     * 是否即将过期（响应时填充）
     */
    private Boolean nearExpiry;
    
    // ==================== 静态方法 ====================
    
    /**
     * 从实体转换为DTO
     * 
     * @param entity 租户实体
     * @return 租户DTO
     */
    public static TenantDTO fromEntity(Tenant entity) {
        if (entity == null) {
            return null;
        }
        
        TenantDTO dto = new TenantDTO();
        dto.setId(entity.getId());
        dto.setTenantId(entity.getTenantId());
        dto.setTenantName(entity.getTenantName());
        dto.setTenantType(entity.getTenantType());
        dto.setStatus(entity.getStatus());
        dto.setMaxUsers(entity.getMaxUsers());
        dto.setExpireTime(entity.getExpireTime());
        dto.setContactName(entity.getContactName());
        dto.setContactPhone(entity.getContactPhone());
        dto.setContactEmail(entity.getContactEmail());
        dto.setDescription(entity.getDescription());
        dto.setCreatedBy(entity.getCreateBy());
        dto.setCreatedAt(entity.getCreateTime());
        dto.setUpdatedBy(entity.getUpdateBy());
        dto.setUpdatedAt(entity.getUpdateTime());
        dto.setDeleted(entity.getDeleted());
        
        // 填充状态描述
        dto.setStatusText(getStatusText(entity.getStatus()));
        
        // 检查是否即将过期（30天内）
        if (entity.getExpireTime() != null) {
            LocalDateTime thirtyDaysLater = LocalDateTime.now().plusDays(30);
            dto.setNearExpiry(entity.getExpireTime().isBefore(thirtyDaysLater));
        } else {
            dto.setNearExpiry(false);
        }
        
        return dto;
    }
    
    /**
     * 转换为实体
     * 
     * @return 租户实体
     */
    public Tenant toEntity() {
        Tenant entity = new Tenant();
        entity.setId(this.id);
        entity.setTenantId(this.tenantId);
        entity.setTenantName(this.tenantName);
        entity.setTenantType(this.tenantType);
        entity.setStatus(this.status);
        entity.setMaxUsers(this.maxUsers);
        entity.setExpireTime(this.expireTime);
        entity.setContactName(this.contactName);
        entity.setContactPhone(this.contactPhone);
        entity.setContactEmail(this.contactEmail);
        entity.setDescription(this.description);
        entity.setCreateBy(this.createdBy);
        entity.setCreateTime(this.createdAt);
        entity.setUpdateBy(this.updatedBy);
        entity.setUpdateTime(this.updatedAt);
        entity.setDeleted(this.deleted);
        
        return entity;
    }
    
    /**
     * 获取状态文本描述
     * 
     * @param status 状态值
     * @return 状态描述
     */
    private static String getStatusText(Integer status) {
        if (status == null) {
            return "未知";
        }
        
        return switch (status) {
            case 0 -> "禁用";
            case 1 -> "正常";
            case 2 -> "试用";
            case 3 -> "过期";
            case 4 -> "待审核";
            default -> "未知";
        };
    }
    
    /**
     * 验证DTO数据的完整性
     */
    public void validate() {
        if (tenantId != null && tenantName != null) {
            // 可以在这里添加自定义验证逻辑
        }
    }
    
    // ==================== Getters and Setters ====================
    
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    
    public String getTenantId() { return tenantId; }
    public void setTenantId(String tenantId) { this.tenantId = tenantId; }
    
    public String getTenantName() { return tenantName; }
    public void setTenantName(String tenantName) { this.tenantName = tenantName; }
    
    public String getTenantType() { return tenantType; }
    public void setTenantType(String tenantType) { this.tenantType = tenantType; }
    
    public Integer getStatus() { return status; }
    public void setStatus(Integer status) { this.status = status; }
    
    public Integer getMaxUsers() { return maxUsers; }
    public void setMaxUsers(Integer maxUsers) { this.maxUsers = maxUsers; }
    
    public LocalDateTime getExpireTime() { return expireTime; }
    public void setExpireTime(LocalDateTime expireTime) { this.expireTime = expireTime; }
    
    public String getContactName() { return contactName; }
    public void setContactName(String contactName) { this.contactName = contactName; }
    
    public String getContactPhone() { return contactPhone; }
    public void setContactPhone(String contactPhone) { this.contactPhone = contactPhone; }
    
    public String getContactEmail() { return contactEmail; }
    public void setContactEmail(String contactEmail) { this.contactEmail = contactEmail; }
    
    public String getDescription() { return description; }
    public void setDescription(String description) { this.description = description; }
    
    public String getCreatedBy() { return createdBy; }
    public void setCreatedBy(String createdBy) { this.createdBy = createdBy; }
    
    public LocalDateTime getCreatedAt() { return createdAt; }
    public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
    
    public String getUpdatedBy() { return updatedBy; }
    public void setUpdatedBy(String updatedBy) { this.updatedBy = updatedBy; }
    
    public LocalDateTime getUpdatedAt() { return updatedAt; }
    public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
    
    public Integer getDeleted() { return deleted; }
    public void setDeleted(Integer deleted) { this.deleted = deleted; }
    
    public Integer getUserCount() { return userCount; }
    public void setUserCount(Integer userCount) { this.userCount = userCount; }
    
    public String getStatusText() { return statusText; }
    public void setStatusText(String statusText) { this.statusText = statusText; }
    
    public Boolean getNearExpiry() { return nearExpiry; }
    public void setNearExpiry(Boolean nearExpiry) { this.nearExpiry = nearExpiry; }
    
    @Override
    public String toString() {
        return "TenantDTO{" +
                "id=" + id +
                ", tenantId='" + tenantId + '\'' +
                ", tenantName='" + tenantName + '\'' +
                ", tenantType='" + tenantType + '\'' +
                ", status=" + status +
                ", maxUsers=" + maxUsers +
                ", expireTime=" + expireTime +
                ", contactName='" + contactName + '\'' +
                ", contactPhone='" + contactPhone + '\'' +
                ", contactEmail='" + contactEmail + '\'' +
                ", description='" + description + '\'' +
                ", userCount=" + userCount +
                ", statusText='" + statusText + '\'' +
                ", nearExpiry=" + nearExpiry +
                '}';
    }
}
